#include "LaneAgent.h"
#include "ScopedLock.h"

	//Constructor
	LaneAgent::LaneAgent(std::string name)
			: Agent(name) 
	{
		laneSpeed = 5;
		factorySpeed = 33;
		state = None;
		testing = false;
		partType = EMPTY;
		psTimer= new PurgeStopTimer(this);
		cnTimer= new CallNestTimer(this);
	}

	//From Nest
	void LaneAgent::msgPleaseGetParts(PartType p) {
		print("Received PartType from NestAgent");
		if( p != partType) {
			partType = p;
			state = Purge;
		} else {
			state = Request_More_Parts;
		}
		stateChanged();
	}

	//From Feeder
	void LaneAgent::msgHereAreParts(PartType p) {
		print("Received Parts From Feeder");
		if(testing == false) {
			cnTimer->start();
		}
		partType = p;
		stateChanged();
	}

	//From Elsewhere
	void LaneAgent::msgYourSpeedNeedsToChange(int speed) {
		changeSpeed(speed);
		stateChanged();
	}

	//Scheduler
	bool LaneAgent::pickAndExecuteAnAction() {
		if(state == Purge) {
			purgeLaneOfParts();
			state = None;
			return true;
		}

		if(state == Request_More_Parts) {
			returnPartTypeToFeeder();
			state = None;
			return true;
		}
		
		if(state == Speed_Changed) {
			tellGUISpeedChanged();
			state = None;
			return true;
		}
		
		return false;
	}

	//To Nest
	void LaneAgent::tellNestItIsFull() {
		nest->msgIThinkYoureFull();
	}

	//To Feeder
	void LaneAgent::returnPartTypeToFeeder() {
		if(partType != EMPTY) {
			feeder->msgPleaseGetParts(partType,this);
		}
	}

	//To Self
	void LaneAgent::purgeLaneOfParts() {
		laneSpeed = 10;
		tellGUISpeedChanged();
		if(testing == false) {
			psTimer->start();
		}
	}

	//To Nest
	void LaneAgent::informPurgingComplete() {
		laneSpeed = 5;
		tellGUISpeedChanged();
		nest->msgPleaseStopPurging();
		returnPartTypeToFeeder();
	}

	//To GUI
	void LaneAgent::tellGUIToStart() {
		guiLane->Start(laneSpeed);
	}

	//To GUI
	void LaneAgent::tellGUIToStop() {
		guiLane->Stop();
	}
	
	//To GUI
	void LaneAgent::tellGUISpeedChanged() {
		if(laneSpeed == 0) {
			tellGUIToStop();
		} else {
			guiLane->setRunSpeed(laneSpeed);
		}
	}

	//Assessors
	void LaneAgent::setGUI(GUILaneInterface* gui) {
		guiLane = gui;
		tellGUIToStart();
	}
	
	void LaneAgent::setFeeder(Feeder* feederAgent) {
		feeder = feederAgent;
	}
	
	void LaneAgent::setNest(Nest* nestAgent) {
		nest = nestAgent;
	}

	GUILane* LaneAgent::getGUI() {
		return (GUILane*)guiLane;
	}

	int LaneAgent::getSpeed() {
		return laneSpeed;
	}

	void LaneAgent::setFactorySpeed(float newSpeed) {
		factorySpeed = newSpeed;
	}

	void LaneAgent::changeSpeed(float newSpeed) {
		laneSpeed = newSpeed;
		state = Speed_Changed;
	}

	void LaneAgent::handleBreak() {
		((GUILane*)guiLane)->DoBreak();
	}

	void LaneAgent::handleFix() {
		((GUILane*)guiLane)->DoFix();
	}